﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace SplenetiX
{
    [Serializable]
    public class Personnage : Character
    {
        enum TypeCollision { None, Gauche, Droite };

        float mvtSpeed, maxWidth, maxHeigth, health, timerShoot;
        //bool isOnGround, isJumping, collisionTop, doubleSaut;
        int lastState;
        //Vector2 vitesse = new Vector2(0, 0);
        Keys keyLeft, keyRight;
        //List<Projectile> projectiles;
        float timerHurt;
        bool isDie = false;

        SpriteAnimation AnimJoueur; 
        SpriteAnimation AnimJoueurMort;

        /*
        public bool IsOnGround
        {
            get { return isOnGround; }
            set { this.isOnGround = value; }
        }
        public bool IsJumping
        {
            get { return isJumping; }
            set { isJumping = value; }
        }

        public Vector2 Vitesse
        {
            get { return vitesse; }
            set { vitesse = value; }
        }
        */
        public float Health { get { return health; } set { health = value; } }
        public bool IsDie { get { return isDie; } }
        //public List<Projectile> Projectiles { get { return projectiles; } }


        // -- Constructeur
        public Personnage(Vector2 position, float maxWidth, float maxHeigth, Keys keyLeft, Keys keyRight)
            : base(position)
        {
            this.maxWidth = maxWidth;
            this.maxHeigth = maxHeigth;
            mvtSpeed = Constant.PlayerSpeed;
            this.keyLeft = keyLeft;
            this.keyRight = keyRight;
            //isOnGround = false;
            //collision = (int)TypeCollision.None;
            //collisionTop = false;
            health = Constant.PlayerHealth;
            //projectiles = new List<Projectile>();
            lastState = 1;
            timerShoot = 0;
            timerHurt = 0;
            //doubleSaut = false;
        }

        //Deplacements actifs et passifs
        public void Move(GameTime gameTime, Level level)
        {
            float deltaT = gameTime.ElapsedGameTime.Milliseconds * 0.01f;

            #region GAUCHE DROITE REINIT LIMITES
            //Reinitialisation position
            if (ServiceHelper.Get<IKeyboardService>().IsKeyDown(Keys.Q))
            {
                Position = new Vector2(150, 0);
            }

            int leftTile = (int)(position.X / Constant.TileSize);
            int rightTile = (int)((position.X + texture.Width + 32) / Constant.TileSize);
            int topTile = (int)Math.Floor((float)position.Y / Constant.TileSize);
            int bottomTile = (int)Math.Ceiling(((float)(position.Y + texture.Height) / Constant.TileSize)) - 1;

            //Gauche
            if (ServiceHelper.Get<IKeyboardService>().IsKeyDown(keyLeft))
            {
                if (Position.X > 0)
                {
                    UpdatePosition(new Vector2(-(mvtSpeed * gameTime.ElapsedGameTime.Milliseconds), 0));
                    position.X = (int)position.X;
                    lastState = -1;
                }
            }

            //Droite
            if (ServiceHelper.Get<IKeyboardService>().IsKeyDown(keyRight))
            {
                if (Position.X < level.Longueur * Constant.TileSize - texture.Width)
                {
                    UpdatePosition(new Vector2(mvtSpeed * gameTime.ElapsedGameTime.Milliseconds, 0));
                    position.X = (int)position.X;
                    lastState = 1;
                }
            }

            //Limite plafond
            if (Position.Y <= 0)
            {
                Position = new Vector2(Position.X, 0);
            }

            //Limite Sol
            if (Position.Y >= level.Hauteur * Constant.TileSize - texture.Height)
            {
                Position = new Vector2(Position.X, Constant.Heigth - texture.Height);
            }
            #endregion

            #region Saut
            if (isOnGround && ServiceHelper.Get<IKeyboardService>().IsKeyDown(Keys.Space) && !doubleSaut)
            {
                base.Jump();
            }
            doubleSaut = ServiceHelper.Get<IKeyboardService>().IsKeyDown(Keys.Space);
            #endregion

            base.Move(deltaT);
        }

        public void LoadJoueur(ContentManager content)
        {
            AnimJoueur = new SpriteAnimation(
                content.Load<Texture2D>("Anim_Personnage//sprite_droit"), 3, 2);

            AnimJoueur.FramesPerSecond = 8;

            AnimationClass ani = new AnimationClass();
            AnimJoueur.AddAnimation("Right", 1, 3, ani.Copy());
            AnimJoueur.AddAnimation("RightIdle", 1, 1, ani.Copy());

            ani.SpriteEffect = SpriteEffects.FlipHorizontally;
            AnimJoueur.AddAnimation("Left", 1, 3, ani.Copy());
            AnimJoueur.AddAnimation("LeftIdle", 1, 1, ani.Copy());

            AnimJoueur.Animation = "RightIdle"; //animation par defaut


            /*Animation mort*/
            AnimJoueurMort = new SpriteAnimation(content.Load<Texture2D>("Anim_Personnage//sang_anim"), 4, 1);
            AnimJoueurMort.FramesPerSecond = 10;
            AnimationClass ani_mort = new AnimationClass();
            ani_mort.IsLooping = false;

            AnimJoueurMort.AddAnimation("Mort", 1, 4, ani_mort);
            AnimJoueurMort.Animation = "Mort";
        }

        ////Affichage a l'ecran du sprite
        //public void Draw(SpriteBatch batch, Rectangle sourceRect)
        //{
        //    batch.Draw(Texture, Position, sourceRect, Color.White);
        //}
        public void DrawJoueur(SpriteBatch batch/*, Rectangle sourceRect*/)
        {
            //batch.Draw(Texture, Position, sourceRect, Color.White);
            if (!this.IsDie)
            {
                AnimJoueur.Draw(batch, this.Position);
            }
            else
            {
                AnimJoueurMort.Draw(batch, this.Position);
                batch.DrawString(Hud.spriteFont, ".: Hey t'es Mort :.", this.Position, Color.White);

            }
        }


        #region Dommages
        //Calcule les degats selon le type d'attaque et les retranche a la vie du joueur
        private void TakeDamage(int type)
        {
            switch (type)
            {
                case 1:
                    health -= Constant.DamageRanged;
                    SoundEngine.PlaySound(SoundEngine.Degats);
                    break;

                default:
                    health -= Constant.BasicDamage;
                    SoundEngine.PlaySound(SoundEngine.Degats);
                    timerHurt = 0f;
                    break;
            }
        }

        //Verifie si le joueur est blesse
        private void Hurt(List<Ennemi> ennemis)
        {
            for (int i = 0; i < ennemis.Count; i++)
            {
                if (timerHurt > 100f && rectangle.Intersects(ennemis[i].Rectangle))
                {
                    TakeDamage(0);
                }

                for (int j = 0; j < ennemis[i].Projectiles.Count; j++)
                {
                    if (ennemis[i].Projectiles[j].Rectangle.Intersects(rectangle))
                    {
                        ennemis[i].Projectiles.RemoveAt(j);
                        TakeDamage(0);
                    }
                }
            }
        }
        #endregion

        //Update general, appelle : move, hurt
        public void Update(GameTime gameTime, Level level, List<Ennemi> ennemis)
        {
            if (timerShoot >= Constant.ShootInterval)
            {
                if (ServiceHelper.Get<IKeyboardService>().IsKeyDown(Keys.LeftControl))
                {
                    Shoot();
                    timerShoot = 0;
                    SoundEngine.PlaySound(SoundEngine.Tir);
                }
            }

            Hurt(ennemis);    

            for (int i = 0; i < projectiles.Count; i++)
            {
                if (projectiles[i].Distance >= Constant.MaxRange)
                {
                    projectiles.RemoveAt(i);
                }
                else
                {
                    projectiles[i].Update(gameTime);
                }
            }

            Move(gameTime, level);
            if (health <= 0)
            {
                isDie = true;
            }

            timerHurt += gameTime.ElapsedGameTime.Milliseconds;
            timerShoot += gameTime.ElapsedGameTime.Milliseconds;


            if (ServiceHelper.Get<IKeyboardService>().IsKeyDown(Keys.Left))
            {

                if (AnimJoueur.Animation != "Left")
                    AnimJoueur.Animation = "Left";

            }
            else if (ServiceHelper.Get<IKeyboardService>().IsKeyDown(Keys.Right))
            {

                if (AnimJoueur.Animation != "Right")
                    AnimJoueur.Animation = "Right";
            }
            else
            {
                if (!AnimJoueur.Animation.Contains("Idle"))
                    AnimJoueur.Animation += "Idle";
            }

            AnimJoueur.Update(gameTime);
            AnimJoueurMort.Update(gameTime);
        }

        private void Shoot()
        {
            projectiles.Add(new Projectile(new Vector2(position.X, position.Y + 0.5f * texture.Height), lastState));
        }

        public void Reset(Level level)
        {
            position = new Vector2(0, (level.Hauteur - 2) * 32);
            health = Constant.PlayerHealth;
            isDie = false;
        }

        public void ChangeHealth(float vieRestante)
        {
            health = vieRestante;
        }
    }
}
